﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WomanMotion.WebApi.Infrastructure.UnifyResult;

namespace WomanMotion.WebApi.Identity.JWT
{
    /// <summary>
    /// jwt token认证扩展方法
    /// </summary>
    public static class AddJWT
    {
        /// <summary>
        /// jwt token认证扩展方法
        /// </summary>
        /// <param name="services"></param>
        public static void AddJwtToken(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    var tokenModel = configuration.GetSection("Jwt").Get<TokenModelJwt>();
                    var secretByte = Encoding.UTF8.GetBytes(tokenModel.Secret);
                    //是否开启https  默认tuer
                    options.RequireHttpsMetadata = false;
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidateIssuer = true,
                        ValidIssuer = tokenModel.Issuer,

                        ValidateAudience = true,
                        ValidAudience = tokenModel.Audience,

                        ValidateLifetime = true,

                        IssuerSigningKey = new SymmetricSecurityKey(secretByte),
                        ClockSkew = TimeSpan.Zero //设置为0分钟 要不然默认5分钟
                    };
                    options.Events = new JwtBearerEvents
                    {
                        //当Token认证不通过
                        OnChallenge = context =>
                        {
                            //此处代码为终止.Net Core默认的返回类型和数据结果，这个很重要哦，必须
                            context.HandleResponse();

                            //自定义自己想要返回的数据结果，我这里要返回的是Json对象，通过引用Newtonsoft.Json库进行转换

                            //自定义返回的数据类型
                            context.Response.ContentType = "application/json";
                            ////自定义返回状态码，默认为401
                            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                            ////输出Json数据结果
                            context.Response.WriteAsync(JsonConvert.SerializeObject(ResultOutput.NotOk("Token认证不通过")));
                            return Task.FromResult(0);
                        },
                        //403 无权限访问
                        OnForbidden = context =>
                        {
                            context.Response.ContentType = "application/json";
                            ////自定义返回状态码，默认为401
                            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                            //context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                            ////输出Json数据结果
                            context.Response.WriteAsync(JsonConvert.SerializeObject(ResultOutput.NotOk("无权限访问")));
                            return Task.FromResult(0);
                        }
                    };
                });
        }
    }
}